home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / ss / anlytc_1.zip / BUF160.ASM < prev    next >
Assembly Source File  |  1985-09-25  |  9KB  |  289 lines

  1.         PAGE ,132
  2.         TITLE   BUF160
  3. ;  MASM 1.25 gave errors on MOV to DD defined words.  Fixed by adding
  4. ;  WORD PTR in appropriate places.  Added comments for previous
  5. ;  versions.                  Ted Shapin,  2/11/85.
  6. ;
  7. ;  The original version
  8. ;  improperly handled one of the keyboard service functions (return
  9. ;  shift key status:  interrupt 16, function 2), and would crash
  10. ;  whenever any program asked for the shift key status.  Apparently
  11. ;  many programs just look this value up for themselves instead of
  12. ;  going through the BIOS, but Epsilon plays by the rules where
  13. ;  possible, and calls this function to determine the shift key
  14. ;  settings.
  15. ;
  16. ;  I've fixed this bug in buf160.asm and am placing these changes in
  17. ;  the public domain.
  18. ;
  19. ;  This file should be assembled to get buf160.obj, which is
  20. ;  linked to get buf160.exe, which in turn is run through exe2bin to
  21. ;  produce buf160.com.  Ignore the "missing stack segment" message from
  22. ;  link.
  23. ;
  24. ;  Steve Doerfler, Lugaru Software, date unknown.
  25. ;
  26. ; Original by John Socha in Softalk for the IBM PC, Nov. 83. Translated
  27. ; to assembler by Jim Gillogly 11/22/83/
  28. ;
  29. VECTORS        SEGMENT    AT 0H
  30.     ORG    9H*4
  31. KEYBOARD_INT_VECTOR    LABEL    DWORD
  32.     ORG    16H*4
  33. KEYBOARD_IO_VECTOR    LABEL    DWORD
  34. VECTORS        ENDS
  35.  
  36. ROM_BIOS_DATA    SEGMENT AT 40H
  37.     ORG    17H
  38. KBD_FLAG    DB    ?
  39.     ORG    1AH
  40. ROM_BUFFER_HEAD    DW    ?
  41. ROM_BUFFER_TAIL    DW    ?
  42. KB_BUFFER    DW    16D DUP    (?)
  43. KB_BUFFER_END    LABEL    WORD
  44. ROM_BIOS_DATA    ENDS
  45. CODE_SEG    SEGMENT
  46.     ASSUME    CS:CODE_SEG
  47.     ORG    100H
  48. BEGIN:    JMP    INIT_VECTORS        ;Initialize vectors and attach to DOS
  49. ROM_KEYBOARD_INT    DD    0    ;[0 needed for MS-MASM 3.00 -rag]
  50. ROM_KEYBOARD_IO        DD    0
  51. BUFFER_HEAD        DW    OFFSET KEYBOARD_BUFFER
  52. BUFFER_TAIL        DW    OFFSET KEYBOARD_BUFFER
  53. KEYBOARD_BUFFER        DW    160D DUP(0)    ;159 character input buffer
  54. KEYBOARD_BUFFER_END    LABEL    WORD
  55.  
  56. ;--------------------------------------------------------;
  57. ; This procedure sends a short beep when the buffer fills
  58. ;--------------------------------------------------------;
  59.  
  60. KB_CONTROL    EQU    61H        ;Control bits for keyboard & speaker
  61. ERROR_BEEP    PROC    NEAR
  62.     PUSH    AX
  63.     PUSH    BX
  64.     PUSH    CX
  65.     PUSHF                ;Save old interupt enable flag
  66.     CLI                ;Turn off beep during interupt
  67.     MOV    BX,30D            ;Number of cycles for 1/8 second tone
  68.     IN    AL,KB_CONTROL        ;Get information from speaker port
  69.     PUSH    AX            ;Save control information
  70. START_OF_ONE_CYCLE:
  71.     AND    AL,0FCH            ;Turn off speaker
  72.     OUT    KB_CONTROL,AL
  73.     MOV    CX,60D            ;Delay for one half cycle
  74. OFF_LOOP:
  75.     LOOP    OFF_LOOP
  76.     OR    AL,2            ;Turn off speaker
  77.     OUT    KB_CONTROL,AL
  78.     MOV    CX,60D            ;Delay for second half cycle
  79. ON_LOOP:
  80.     LOOP    ON_LOOP
  81.     DEC    BX            ;200 cycles yet?
  82.     JNZ    START_OF_ONE_CYCLE
  83.     POP    AX            ;Recover old keyboard information
  84.     OUT    KB_CONTROL,AL
  85.     POPF                ;Restore interupt flag
  86.     POP    CX
  87.     POP    BX
  88.     POP    AX
  89.     RET
  90. ERROR_BEEP    ENDP
  91.  
  92. ;This procedure checks the ROM keyboard buffer to see if some program
  93. ;tried to clear this buffer. We know it's been cleared when the ROM
  94. ;tail and header overlap. Normally, the new procedures below keep the
  95. ;dummy character, word 0,in the buffer.
  96. ;
  97. ;Uses: BX,DS
  98. ;Writes:    BUFFER_HEAD,BUFFER_TAIL,ROM_BUFFER_HEAD,
  99. ;        ROM_BUFFER_TAIL
  100. ;Reads:        KEYBOARD_BUFFER,KB_BUFFER
  101.  
  102. CHECK_CLEAR_BUFFER    PROC NEAR
  103.     ASSUME    DS:ROM_BIOS_DATA
  104.     MOV    BX,ROM_BIOS_DATA    ;Establish pointer to BIOS data
  105.     MOV    DS,BX
  106.     CLI                ;Turn off interupts during this check
  107.     MOV    BX,ROM_BUFFER_HEAD    ;check to see if buffer cleared
  108.     CMP    BX,ROM_BUFFER_TAIL    ;Is the buffer empty?
  109.     JNE    BUFFER_OK        ;No, then everything is alright
  110.                     ;Yes, then clear the internal buffer
  111.     MOV    BX,OFFSET KB_BUFFER    ;Reset buffer with word 0 in buffer
  112.     MOV    ROM_BUFFER_HEAD,BX
  113.     ADD    BX,2
  114.     MOV    ROM_BUFFER_TAIL,BX
  115.     ASSUME    DS:CODE_SEG
  116.     MOV    BX,CS
  117.     MOV    DS,BX
  118.     MOV    BX,OFFSET KEYBOARD_BUFFER ;Reset internal buffer
  119.     MOV    BUFFER_HEAD,BX
  120.     MOV    BUFFER_TAIL,BX
  121. BUFFER_OK:
  122.     ASSUME    DS:CODE_SEG
  123.     STI                ;Interupts back on
  124.     RET
  125. CHECK_CLEAR_BUFFER    ENDP
  126.  
  127. ;This procedure intercepts the keyboard interrupt and moves any new
  128. ;characters to the internal, 80 character buffer.
  129.  
  130. INTERCEPT_KEYBOARD_INT    PROC    NEAR
  131.     ASSUME    DS:NOTHING
  132.     PUSH    DS
  133.     PUSH    SI
  134.     PUSH    BX
  135.     PUSH    AX
  136.     CALL    CHECK_CLEAR_BUFFER    ;Check for buffer cleared
  137.     PUSHF
  138.     CALL    ROM_KEYBOARD_INT    ;Read scan code with BIOS routines
  139. ;-----    Transfer any characters to internal buffer
  140.     ASSUME    DS:ROM_BIOS_DATA
  141.     MOV    BX,ROM_BIOS_DATA    ;Establish pointer to BIOS data
  142.     MOV    DS,BX
  143.     MOV    SI,BUFFER_TAIL
  144.     MOV    BX,ROM_BUFFER_HEAD    ;Check if real characters in buffer
  145.     INC    BX            ;Skip over dummy character
  146.     INC    BX
  147.     CMP    BX,OFFSET KB_BUFFER_END
  148.     JB    DONT_WRAP        ;No need to wrap the pointer
  149.     MOV    BX,OFFSET KB_BUFFER    ;Wrap the pointer
  150. DONT_WRAP:
  151.     CMP    BX,ROM_BUFFER_TAIL    ;Is there a real character?
  152.     JE    NO_NEW_CHARACTERS    ;No then return to caller
  153.     MOV    AX,[BX]            ;Yes,move character to internal buffer
  154.     MOV    CS:[SI],AX
  155.     INC    SI
  156.     INC    SI            ;Move to next position
  157.     CMP    SI,OFFSET KEYBOARD_BUFFER_END
  158.     JB    NOT_AT_END
  159.     MOV    SI,OFFSET KEYBOARD_BUFFER
  160. NOT_AT_END:
  161.     CMP    SI,BUFFER_HEAD        ;Buffer overrun?
  162.     JNE    WRITE_TO_BUFFER        ;Yes beep and throw out character
  163.     CALL    ERROR_BEEP
  164.     JMP    SHORT NOT_AT_KB_END
  165. WRITE_TO_BUFFER:
  166.     MOV    BUFFER_TAIL,SI
  167. NOT_AT_KB_END:
  168.     MOV    ROM_BUFFER_HEAD,BX
  169.  
  170. NO_NEW_CHARACTERS:
  171. ;----    See if CTRL + ALT pushed, and clear buffer if so
  172.  
  173.     MOV    AL,KBD_FLAG        ;Get status of shift keys into AL
  174.     AND    AL,0CH            ;Isolate Alt and Crtl shift flags
  175.     CMP    AL,0CH            ;Are both the Alt and Crtl keys down?
  176.     JNE    DONT_CLEAR_BUFFER    ;No, then dont clear the buffer
  177.     MOV    AX,BUFFER_TAIL        ;Yes, then clear the buffer
  178.     MOV    BUFFER_HEAD,AX
  179.  
  180. DONT_CLEAR_BUFFER:
  181.     POP    AX
  182.     POP    BX
  183.     POP    SI
  184.     POP    DS
  185.     IRET
  186. INTERCEPT_KEYBOARD_INT ENDP
  187.  
  188. ;-----------------------------------------------------------------------;
  189. ;This procedure replaces the ROM BIOS routines for reading a character  ;
  190. ;-----------------------------------------------------------------------;
  191.     ASSUME    DS:CODE_SEG
  192. INTERCEPT_KEYBOARD_IO PROC    FAR
  193.     STI                ;Interrupts back on
  194.     PUSH    DS            ;Save current DS
  195.     PUSH    BX            ;Save BX temporarily
  196.     CALL    CHECK_CLEAR_BUFFER    ;Check for buffer cleared
  197.     MOV    BX,CS            ;Establish pointer to data area
  198.     MOV    DS,BX
  199.     OR    AH,AH            ;AH=0?
  200.     JZ    READ_CHARACTER        ;Yes, read a character
  201.     CMP    AH,1            ;AH=1?
  202.     JE    READ_STATUS        ;Yes, return the status
  203.  
  204.     POP    BX            ;Pass other calls to the rom bios
  205.     POP    DS
  206.     ASSUME    DS:NOTHING
  207.     JMP    ROM_KEYBOARD_IO        ;Let ROM routines do this
  208.     ASSUME    DS:CODE_SEG
  209.  
  210. ;----    Read the key
  211.  
  212. READ_CHARACTER:                ;ASCII read
  213.     STI                ;Interrupts back on during loop
  214.     NOP                ;Allow an interrupt to occur
  215.     CLI                ;Interrupts back off
  216.     MOV    BX,BUFFER_HEAD        ;Get pointer to head of buffer
  217.     CMP    BX,BUFFER_TAIL        ;Test end of buffer
  218.     JE    READ_CHARACTER        ;Loop until something in buffer
  219.     MOV    AX,[BX]            ;Get scan code and ASCII code
  220.     ADD    BX,2            ;Move to next word in buffer
  221.     CMP    BX,OFFSET KEYBOARD_BUFFER_END    ;At end of buffer?
  222.     JNE    SAVE_POINTER        ;No, continue
  223.     MOV    BX,OFFSET KEYBOARD_BUFFER    ;Yes, reset to buffer start
  224. SAVE_POINTER:
  225.     MOV    BUFFER_HEAD,BX        ;Store value in variable
  226.     POP    BX
  227.     POP    DS
  228.     IRET                ;Return to caller
  229.  
  230. ;----    ASCII status
  231.  
  232. READ_STATUS:
  233.     CLI                ;Interrupts off
  234.     MOV    BX,BUFFER_HEAD        ;Get head pointer
  235.     CMP    BX,BUFFER_TAIL        ;If equal (ZF=1) then nothing there
  236.     MOV    AX,[BX]
  237.     STI                ;Interrupts back on
  238.     POP    BX            ;Recover registers
  239.     POP    DS
  240.     RET    2            ;Throw away flags
  241.  
  242. INTERCEPT_KEYBOARD_IO    ENDP
  243.  
  244. ;-----------------------------------------------------------------;
  245. ;This procedure initializes the interrupt vectors.          ;
  246. ;-----------------------------------------------------------------;
  247. INIT_VECTORS    PROC    NEAR
  248.     ASSUME    DS:VECTORS
  249.     PUSH    DS            ;Save old Data Segment
  250.     MOV    AX,VECTORS        ;Set up the data segment for vectors
  251.     MOV    DS,AX
  252.     CLI                ;Dont allow interrupts
  253.  
  254.     MOV    AX,WORD PTR KEYBOARD_INT_VECTOR    ;Save addresses of BIOS routines
  255.     MOV    WORD PTR ROM_KEYBOARD_INT,AX
  256.     MOV    AX,WORD PTR KEYBOARD_INT_VECTOR[2]
  257.     MOV    WORD PTR ROM_KEYBOARD_INT[2],AX
  258.                     ;Set up new KEYBOARD_INT vector
  259.     MOV    WORD PTR KEYBOARD_INT_VECTOR,OFFSET INTERCEPT_KEYBOARD_INT
  260.     MOV    WORD PTR KEYBOARD_INT_VECTOR[2],CS
  261.     STI                ;Allow interrupts again
  262.                     ;Set up KEYBOARD_IO vector
  263.     MOV    AX,WORD PTR KEYBOARD_IO_VECTOR
  264.     MOV    WORD PTR ROM_KEYBOARD_IO,AX
  265.     MOV    AX,WORD PTR KEYBOARD_IO_VECTOR[2]
  266.     MOV    WORD PTR ROM_KEYBOARD_IO[2],AX
  267.     MOV    WORD PTR KEYBOARD_IO_VECTOR,OFFSET INTERCEPT_KEYBOARD_IO
  268.     MOV    WORD PTR KEYBOARD_IO_VECTOR[2],CS
  269.                     ;Now set up the the kbd buffer, etc.
  270.  
  271.     ASSUME    DS:ROM_BIOS_DATA
  272.     MOV    AX,ROM_BIOS_DATA
  273.     MOV    DS,AX
  274.     CLI                ;Dont allow interrupts now
  275.     MOV    BX,OFFSET KB_BUFFER
  276.     MOV    ROM_BUFFER_HEAD,BX
  277.     MOV    WORD PTR [BX],0
  278.     ADD    BX,2
  279.     MOV    ROM_BUFFER_TAIL,BX
  280.     STI                ;Allow interrupts again
  281.  
  282.     MOV    DX,OFFSET INIT_VECTORS    ;End of resident portions
  283.     INT    27H            ;Terminate but stay resident
  284. INIT_VECTORS    ENDP
  285.  
  286. CODE_SEG    ENDS
  287.  
  288.     END    BEGIN
  289.